// Interact.cpp

// Implementacia interaktivneho rozhrania

#include "Common/Interact.h"
#include "Common/Support/Debug.h"
#include "Common/Tasks.h"
#include <stdio.h>
#include <string.h>

#ifdef WIN32
	#include <conio.h>
#else	// WIN32
	#include <sys/types.h>
	#include <sys/time.h>
	#include <unistd.h>
#endif	// WIN32


Interact::Interact() : Module("Interact", "Interaktivny modul", "v0.16")
{
	m_pSocket		= NULL;
	m_pCommandGen	= NULL;
	m_bInit			= false;
	m_bAuto			= false;
	m_bGoalie		= false;
	strcpy(m_strTeamName, "Moj tim");
	strcpy(m_strServer, "localhost");

#ifdef COACH
	m_uPort = 6002;
#else // COACH
	m_uPort = 6000;
	clangInit = false;
#endif // COACH
	m_strBuf[0]		= 0;
	m_strLast[0]	= 0;
	m_iPos			= 0;

	if(Main::GetInstance()->RegisterModule(this, USER_INTERACTION_TASK))
	{
		//TXTN("Interact: Register OK");
	}
	else
	{
		ERRN("Interact: Registrovanie modulu zlyhalo\n\tZastavenie systemu");
		Main::GetInstance()->ShutDown();	// Nie je to korektne, volat ShutDown v konstruktore
	}
}


int Interact::Init(int argc, char** argv, int)
{
	m_pSocket = (CommunicationInterface*) Main::GetInstance()->GetInterface(COMMUNICATION_TASK);
	
	if (m_pSocket == NULL) 
		return INIT_ERR;

	m_pCommandGen = (CommandsInterface*) Main::GetInstance()->GetInterface(COMMANDS_TASK);
	
	if (m_pCommandGen == NULL)
		return INIT_ERR;

	for (int i = 1; i < argc; i++)
	{
		if (strcmp(argv[i], "-h") == 0)
		{
			fprintf(stderr, "\n%s %s Prepinace:\n\n", (char*)GetName(), (char*)GetVersion());
			fprintf(stderr, "\t-h: tento help\n");
			fprintf(stderr, "\t-a: neinteraktivne automaticke spustenie\n");
			fprintf(stderr, "\t-g: povie hracovi, aby sa pripojil ako brankar\n");
			fprintf(stderr, "\t-s <server>: specifikuje nazov servera pre pripojenie\n");
			fprintf(stderr, "\t-p <port>: specifikuje port servera pre pripojenie\n");
			fprintf(stderr, "\t-n <name>: specifikuje meno timu hraca\n\n");
			return INIT_ERR;
		}
		else if (strcmp(argv[i], "-a") == 0)
		{
			m_bAuto = true;
		}
		else if (strcmp(argv[i], "-g") == 0)
		{
			m_bGoalie = true;
		}
		else if (strcmp(argv[i], "-s") == 0)
		{
			if (argv[++i])
				strncpy(m_strServer, argv[i], 32);
		}
		else if (strcmp(argv[i], "-p") == 0)
		{
			if (argv[++i]) 
				sscanf(argv[i], "%d", &m_uPort);
		}
		else if (strcmp(argv[i], "-n") == 0)
		{
			if (argv[++i])
				strncpy(m_strTeamName, argv[i], 32);
		}
	}

	return INIT_OK;
}

void Interact::Run(int)
{
	if (m_bAuto && !m_bInit)
	{
		m_pSocket->SetServer(m_strServer, m_uPort);
		m_pCommandGen->ServerInit(m_strTeamName, m_bGoalie);
    if (m_bGoalie) m_pCommandGen->Reconnect(m_strTeamName, 1); //pre istotu
		m_bInit = true;
		return;
	}

#ifndef COACH
	if(!clangInit)
	{
		m_pCommandGen->CLangInit();
		clangInit = true;
	}
#endif

	// Nasledujuci kod postrada zmysel
	// O co islo jeho ... autorom?
#ifdef WIN32
	if (kbhit()) 
		m_strBuf[m_iPos++] = getche();

	if ((m_iPos == 0) || (m_strBuf[m_iPos-1] != '\r'))
		return;

	printf("\n");
	m_strBuf[m_iPos] = '\0';


#else	// WIN32
	fd_set rfds;
	struct timeval tv;
	int retval;

	FD_ZERO(&rfds);
	FD_SET(0, &rfds);
	tv.tv_sec = 0;
	tv.tv_usec = 0;

	retval = select(1, &rfds, NULL, NULL, &tv);
	/*if(retval)
		fgets(m_strBuf, 128, stdin);
	else
		return;*/
  if (retval == 0) return; //bobor
  if (fgets(m_strBuf, 128, stdin) == NULL) return; //bobor

#endif	// WIN32
	float fNum1, fNum2;

	if ((m_strBuf[0] == '\r') || (m_strBuf[0] == '\n'))
		strcpy(m_strBuf, m_strLast);
	else
		strcpy(m_strLast, m_strBuf);
	
	if (m_bAuto)
	{
		m_pCommandGen->Disconnect();
		Main::GetInstance()->ShutDown();
	}
	else if (strncmp(m_strBuf, "init", 4) == 0)
	{
		if (!m_bInit)
		{
			m_pSocket->SetServer(m_strServer, m_uPort);
			m_pCommandGen->ServerInit(m_strTeamName, m_bGoalie);
			m_bInit = true;
		}
	}
	else if (strncmp(m_strBuf, "bye", 3) == 0)
	{
		m_pCommandGen->Disconnect();
	}
	else if (strncmp(m_strBuf, "dash", 4) == 0)
	{
		sscanf(m_strBuf + 5, "%f", &fNum1);
		m_pCommandGen->Dash(fNum1);
	}
	else if (strncmp(m_strBuf, "kick", 4) == 0)
	{
		sscanf(m_strBuf + 5, "%f %f", &fNum1, &fNum2);
		m_pCommandGen->Kick(fNum1, fNum2);
	}
	else if (strncmp(m_strBuf, "turn", 4) == 0)
	{
		sscanf(m_strBuf + 5, "%f", &fNum1);
		m_pCommandGen->Turn(fNum1);
	}
	else if (strncmp(m_strBuf, "move", 4) == 0)
	{
		sscanf(m_strBuf + 5, "%f %f", &fNum1, &fNum2);
		m_pCommandGen->Move(fNum1, fNum2);
	}
	else if (strncmp(m_strBuf, "exit", 4) == 0)
	{
		m_pCommandGen->Disconnect();
		Main::GetInstance()->ShutDown();
	}
	m_strBuf[0] = 0;
	m_iPos		= 0;

}

